package ch.zhaw.skuh.turing.model.turingmaschine;

import java.math.BigInteger;

import ch.zhaw.skuh.turing.controller.Factory;
import ch.zhaw.skuh.turing.model.turingmaschine.rules.NG_Multiplication;

public class NG_Multiplication_N_ary extends Multiplication_N_ary {

	public static int COUNTSTATES = 4;
	private static int ACCEPT = 3;

	protected static int STARTSTATE = 0;

	protected static int TAPES = 4;

	private static String NAME = "Multiplication, radix=";
	
	private BigInteger[] input;

	public NG_Multiplication_N_ary(int radix) {
		super(radix, new int[]{radix + ACCEPT}, TAPES, COUNTSTATES + radix, NAME + Integer.toString(radix));
	}

	protected NG_Multiplication_N_ary(int radix, int[] acceptStates, int tapes,
			int countStates, String name) {
		super(radix, acceptStates, tapes, countStates, name);
	}

	// 2 numbers, to tapes 1 and 2
	public void setTapes(String input) {
		String[] listString = input.split(Factory.DELIMITER);
		BigInteger[] biInput = new BigInteger[2];
		for (int i = 0; i < listString.length; i++) {
			biInput[i] = new BigInteger(listString[i]);
		}
		int[] tapes = new int[] { 0, 1 };
		setTapes(biInput, tapes);
		setCalcResult(biInput);

		// rules cannot be added until now
		tapes = new int[] { 0, 1, 2, 3 };
		initRules(tapes);
	}

	// load rule-set
	protected void initRules(int[] tapes) {
		// everything in tapes 1-4
		int[] tapesCurrent = new int[] { tapes[0], tapes[1], tapes[2], tapes[3] };

		// load addition rule-set
		NG_Multiplication rules = new NG_Multiplication(this);
		rules.setRules(0, radix + 3, 4, tapesCurrent);
	}

	protected void setTapes(BigInteger[] input, int[] tapes) {
		char[][] charInput = new char[getTapeCount()][];
		int[] pos = new int[getTapeCount()];
		
		this.input = input;

		// fill tapes
		for (int i = 0; i < tapes.length; i++) {
			// fill tape
			charInput[tapes[i]] = input[i].toString(radix).toCharArray();
			// set position to last char
			pos[tapes[i]] = charInput[tapes[i]].length - 1;
		}
		// call super class method (which handles the rest)
		setTapes(charInput, pos, STARTSTATE + radix);
	}
	
	

	public String getResultPrediction() {
		return getCalcResult();
	}

	public String getCalcResult() {
		calcResult = BigInteger.ONE;
		for (int i = 0; i < this.input.length; i++) {
			// calc result
			calcResult = calcResult.multiply(input[i]);
		}
		return calcResult.toString();
	}
	
	protected void setCalcResult(BigInteger[] input) {
		//do nothing
	}

}
